<!DOCTYPE html>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script>
// Waits for a message in the isolated world, posts its string representation
// back to the main world, and resolves the promise with it. Not durable to
// multiple such messages being in-flight at once.
function awaitMessageInIsolatedWorld() {
  testRunner.evaluateScriptInIsolatedWorld(1,
      `window.addEventListener('message', function listener({ data: { origin, data }}) {
        if (origin == 'main') {
          window.postMessage({ origin: 'isolated', data: data.toString() }, '*');
          window.removeEventListener('message', listener);
        }
      });`);

  return new Promise((resolve, reject) => {
    window.addEventListener('message', function listener({ data: { origin, data }}) {
      if (origin == 'isolated') {
        resolve(data);
        window.removeEventListener('message', listener);
      }
    });
  });
}

// Like awaitMessageInIsolatedWorld, but listens in the main world.
function awaitMessageInMainWorld() {
  return new Promise((resolve, reject) => {
    window.addEventListener('message', function listener({ data: { origin, data }}) {
      if (origin == 'main') {
        resolve(data.toString());
        window.removeEventListener('message', listener);
      }
    });
  });
}

promise_test(async () => {
  let mainPromise = awaitMessageInMainWorld();
  let isolatedPromise = awaitMessageInIsolatedWorld();

  let typedArray = new Uint8Array([1, 2, 3, 4]);
  let typedArrayAsString = typedArray.toString();
  window.postMessage({ origin: 'main', data: typedArray }, '*', [typedArray.buffer]);

  assert_equals(await mainPromise, typedArrayAsString);
  assert_equals(await isolatedPromise, typedArrayAsString);
}, "Transferred array buffers can be read from messages in multiple worlds.");

promise_test(async () => {
  let mainPromise = awaitMessageInMainWorld();
  let isolatedPromise = awaitMessageInIsolatedWorld();

  let imageBitmap = await createImageBitmap(new ImageData(2, 2));
  let imageBitmapAsString = imageBitmap.toString();
  window.postMessage({ origin: 'main', data: imageBitmap }, '*', [imageBitmap]);

  assert_equals(await mainPromise, imageBitmapAsString);
  assert_equals(await isolatedPromise, imageBitmapAsString);
}, "Transferred image bitmaps can be read from messages in multiple worlds.");
</script>
